package chapter06._03_InnerClassTest;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Instant;

/**
 * @Version:
 * @Description: 内部类基础认识
 * @LastDate: 2020/10/2
 */
public class Test02_LocalInnerClass {

    public static void main(String[] args) {
        var clock = new TalkingClock02();
        clock.start(1000, true);

        JOptionPane.showMessageDialog(null, "Quit?");
        System.exit(0);
    }
}

class TalkingClock02 {
    private int interval;
    private boolean beep;


    public void start(int interval, boolean beep) {
        /*
        * 尝试声明一个局部内部类
        * 注意！局部类
        * 不能有修饰符
        * 作用域只有被声明的这块代码中
        * 对外部类隐藏 在这里除了start方法 没有人能知道局部内部类的存在
        * */
        class TimePrinter implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("the time is " + Instant.ofEpochMilli(e.getWhen()));
                /*
                * 局部内部类还有一个好处
                * 由于处于局部的域
                * 所以还能访问局部变量
                * */
                //此时访问的不再是外部类的字段 而是局部变量beep
                if (beep) Toolkit.getDefaultToolkit().beep();
            }
        }

        /*
        * start主体代码
        * 具体实现流程：
        * 1.进入start方法
        * 2.调用局部类的默认构造器 生成一个对象
        * 3.调用Timer 开始计时
        * 4.TalkingClock02.start方法结束 所有局部变量和局部类消失
        *
        * 因为消失后 需要用到局部变量 所以会把局部变量隐式复制给局部类的字段
        * 事实上编译器也是这么做的 把所有局部变量 复制到构造器初始化局部类的字段值
        * */
        var lisener = new TimePrinter();
        var timer = new Timer(interval, lisener);//此时访问的不再是外部类的字段 而是局部变量interval
        timer.start();
    }
}
